#include "StdAfx.h"
#include "IconHelper.h"

using namespace Adaptive::Win32;

/*--------------------------------------------------------------------------------
 * Constructor / Dispose / Destructor Methods
 *------------------------------------------------------------------------------*/
#pragma region Constructor / Dispose / Destructor Methods
// <summary>
// Initializes a new instance of the class.
// </summary>
// <remarks>
// This Constructor is hidden to prevent instantiation.
// </remarks>
IconHelper::IconHelper()
{
}
#pragma endregion

/*--------------------------------------------------------------------------------
 * Public Methods / Functions
 *------------------------------------------------------------------------------*/
#pragma region Protected Methods / Functions
// <summary>
// Gets a copy of the desktop icon.
// </summary>
// <returns>
// An <see cref="Icon"/> instance.
// </returns>
Icon^ IconHelper::DesktopIcon()
{
	return GetShellIcon(34, false);
}
Icon^ IconHelper::GetShellFolderIcon(bool large, bool selected)
{
	Icon^ returnValue = nullptr;
	int index = 3;

	if (selected)
		index = 4;

	returnValue = GetShellIcon(index, large);
	return returnValue;
}
Icon^ IconHelper::GetShellIcon(int index, bool large)
{
	String^ pathName = System::Environment::SystemDirectory + "\\shell32.dll";
	CString wideName = pathName;
	HICON* largeIcons = NULL;
	HICON* smallIcons = NULL;
	Icon^	returnValue = nullptr;

	largeIcons = new HICON[1];
	smallIcons = new HICON[1];

	ExtractIconEx(wideName, index, largeIcons, smallIcons, 1);
	if (large)
	{
		returnValue = Icon::FromHandle(IntPtr::IntPtr(largeIcons[0]));
	}
	else
	{
		returnValue = Icon::FromHandle(IntPtr::IntPtr(smallIcons[0]));
	}

	delete(largeIcons);
	delete(smallIcons);

	return returnValue;
}
// <summary>
// Translates the specified icon instance to a bitmap, with alpha blending.
// </summary>
// <param name="iconToTranslate">The <see cref="Icon"/> instance to be translated.</param>
// <returns>
// A <see cref="Bitmap"/> version of the specified icon image.
// </returns>
Bitmap^ IconHelper::IconToBitmap(Icon^ iconToTranslate)
{
	Bitmap^ returnValue = nullptr;
	Graphics^ g = nullptr;

	if (iconToTranslate != nullptr)
	{
		//Create bitmap instance of same size.
		returnValue = gcnew Bitmap(iconToTranslate->Size.Width, iconToTranslate->Size.Height);

		//Create drawing object to draw on bitmap with.
		g = Graphics::FromImage(returnValue);

		//"Draw" the icon onto the bitmap.
		g->DrawIcon(iconToTranslate, 0, 0);
		delete(g);
		g=nullptr;
	}

	return returnValue;
}
// <summary>
// Gets the Windows related icon image for the specified file.
// </summary>
// <param name="fileName">A string that contains the path and file name. Both absolute and relative paths are valid.</param>
// <param name="selected">A value indicating whether to get the icon for a "selected" item.</param>
// <param name="smallIcon">A value indicating whether to get the small or large icon.</param>
// <returns>
// A <see cref="Icon"/> image.
// </returns>
Icon^ IconHelper::GetIcon(System::String ^fileName, bool selected, bool smallIcon)
{
	CString wideName = fileName;
	SHFILEINFO info;
	UINT structSize = 0;
	UINT flags = 0;
	Icon^ returnValue = nullptr;
	int error = 0;

	structSize = sizeof(info);

	flags = SHGFI_ICON | SHGFI_USEFILEATTRIBUTES ;
	if (selected)
		flags = flags | SHGFI_OPENICON;

	if (smallIcon)
		flags = flags | SHGFI_SMALLICON;
	else
		flags = flags | SHGFI_LARGEICON;

	info.dwAttributes = flags;
	if (SHGetFileInfo(wideName, FILE_ATTRIBUTE_NORMAL, &info, structSize, flags))
	{
		returnValue = Icon::FromHandle(IntPtr::IntPtr(info.hIcon));
	}
	else
	{
		error = GetLastError();
	}

	return returnValue;
}
#pragma endregion
